
using System;
using System.Data;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

using Abp.UI;
using Abp.AutoMapper;
using Abp.Extensions;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Application.Services.Dto;
using Abp.Linq.Extensions;


using Yozeev.BusinessLogic;
using Yozeev.BusinessLogic.Dtos;
using Yozeev.BusinessLogic.DomainService;
using Yozeev.BusinessLogic.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Yozeev.BusinessLogic.BoatBasic.ExcelDto;
using Yozeev.IO.ExcelHelper;
using Abp.Domain.Entities.Auditing;
using Yozeev.Common;
using Abp.Authorization.Users;

namespace Yozeev.BusinessLogic
{
	/// <summary>
	/// Route应用层服务的接口实现方法  
	///</summary>
	[AbpAuthorize]
	public class RouteAppService : YozeevAppServiceBase, IRouteAppService
	{
		private readonly IRepository<Route, Guid> _entityRepository;

		private readonly IRepository<Boat, Guid> _boatRepository;

		private readonly IRepository<Schedule, Guid> _scheduleRository;

		private readonly IRouteManager _entityManager;

		private readonly IExcelHelper _excelHelper;

		private readonly IQueryHelper _queryHelper;
		/// <summary>
		/// 构造函数 
		///</summary>
		public RouteAppService(
		IRepository<Route, Guid> entityRepository
		, IRouteManager entityManager
			,IExcelHelper excelHelper
			, IRepository<Boat, Guid> boatRepository
			,IRepository<Schedule, Guid> scheduleRository
			,IQueryHelper queryHelper
		)
		{
			_entityRepository = entityRepository;
			_entityManager = entityManager;
			_excelHelper = excelHelper;
			_boatRepository = boatRepository;
			_scheduleRository = scheduleRository;
			_queryHelper = queryHelper;
		}


		/// <summary>
		/// 获取Route的分页列表信息
		///</summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[HttpPost]
		public async Task<PagedResultDto<RouteListDto>> GetPaged(GetRoutesInput input)
		{
			//var query = from entityChangeSet in _entityChangeSetRepository.GetAll()
			//			join entityChange in _entityChangeRepository.GetAll() on entityChangeSet.Id equals entityChange.EntityChangeSetId
			//			join user in _userRepository.GetAll() on entityChangeSet.UserId equals user.Id
			//			where entityChange.ChangeTime >= input.StartDate && entityChange.ChangeTime <= input.EndDate
			//			select new EntityChangeAndUser
			//			{
			//				EntityChange = entityChange,
			//				User = user
			//			};
			var expression = _queryHelper.WhereExp<Route>(input.queryData);
			if (AbpUserBase.AdminUserName != GetCurrentUser().UserName)
				expression = _queryHelper.SetWhereExp<Route>(expression, GetViewTypeEnum<Route>(), await GetBranchUser());
			var query = _entityRepository.GetAll().Where(expression);
			// TODO:根据传入的参数添加过滤条件


			var count = await query.CountAsync();

			var entityList = await query
					.OrderBy(input.Sorting).AsNoTracking()
					.PageBy(input)
					.ToListAsync();

			// var entityListDtos = ObjectMapper.Map<List<RouteListDto>>(entityList);
			var entityListDtos = entityList.MapTo<List<RouteListDto>>();

			return new PagedResultDto<RouteListDto>(count, entityListDtos);
		}


		/// <summary>
		/// 通过指定id获取RouteListDto信息
		/// </summary>
		public async Task<RouteListDto> GetById(EntityDto<Guid> input)
		{
			var entity = await _entityRepository.GetAsync(input.Id);

			return entity.MapTo<RouteListDto>();
		}

		/// <summary>
		/// 获取编辑 Route
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task<GetRouteForEditOutput> GetForEdit(NullableIdDto<Guid> input)
		{
			var output = new GetRouteForEditOutput();
			RouteEditDto editDto;

			if (input.Id.HasValue)
			{
				var entity = await _entityRepository.GetAsync(input.Id.Value);

				editDto = entity.MapTo<RouteEditDto>();

				//routeEditDto = ObjectMapper.Map<List<routeEditDto>>(entity);
			}
			else
			{
				editDto = new RouteEditDto();
			}

			output.Route = editDto;
			return output;
		}


		/// <summary>
		/// 添加或者修改Route的公共方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task CreateOrUpdate(CreateOrUpdateRouteInput input)
		{

			if (input.Route.Id.HasValue)
			{
				await Update(input.Route);
			}
			else
			{
				await Create(input.Route);
			}
		}


		/// <summary>
		/// 新增Route
		/// </summary>
		protected virtual async Task<RouteEditDto> Create(RouteEditDto input)
		{
			//TODO:新增前的逻辑判断，是否允许新增

			// var entity = ObjectMapper.Map <Route>(input);
			var entity = input.MapTo<Route>();


			entity = await _entityRepository.InsertAsync(entity);
			return entity.MapTo<RouteEditDto>();
		}

		/// <summary>
		/// 编辑Route
		/// </summary>
		protected virtual async Task Update(RouteEditDto input)
		{
			//TODO:更新前的逻辑判断，是否允许更新

			var entity = await _entityRepository.GetAsync(input.Id.Value);
			input.MapTo(entity);

			// ObjectMapper.Map(input, entity);
			await _entityRepository.UpdateAsync(entity);
		}



		/// <summary>
		/// 删除Route信息的方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task Delete(EntityDto<Guid> input)
		{
			//TODO:删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(input.Id);
		}



		/// <summary>
		/// 批量删除Route的方法
		/// </summary>
		public async Task BatchDelete(List<Guid> input)
		{
			// TODO:批量删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(s => input.Contains(s.Id));
		}


		/// <summary>
		/// 导出Route为excel表,等待开发。
		/// </summary>
		/// <returns></returns>
		//public async Task<FileDto> GetToExcel()
		//{
		//	var users = await UserManager.Users.ToListAsync();
		//	var userListDtos = ObjectMapper.Map<List<UserListDto>>(users);
		//	await FillRoleNames(userListDtos);
		//	return _userListExcelExporter.ExportToFile(userListDtos);
		//}

		// <summary>
		// 从Excel表导入数据
		// </summary>
		[HttpPost]
		public async Task<ExcelResultDto> ImportRoute(IFormFile file)
		{
			string errorMessage = "";
			bool result;
			try
			{
				List<RouteExcelDto> data = _excelHelper.ReadToList<RouteExcelDto>(file);
				var routes = new List<Route>();
				foreach (var dto in data)
				{
					routes.Add(new Route
					{
						LineCode = dto.LineCode,
						RouteName=dto.RouteName,
						LineImage = dto.LineImage,
						LineInfo = dto.LineInfo,
						StartPosition = dto.StartPosition,
						EndPosition = dto.EndPosition,
						AuditStatus = AuditStatusEnum.WaiteAudit,
						CreationTime = DateTime.Now,
						CreatorUserId = AbpSession.UserId,
						Id = Guid.NewGuid(),
					});
				}
				result = await _entityManager.RouteInsertAsync(routes);
			}
			catch (Exception e)
			{
				result = false;
				errorMessage = e.Message;
			}
			return new ExcelResultDto { Result = result, ErrorMessage = errorMessage };
		}


	}
}


